/**
 * PDF 导出 Hook
 * 使用 html2pdf.js 将 HTML 内容导出为 PDF
 * 
 * 功能：
 * - 将指定 DOM 元素转换为 PDF
 * - 支持自定义文件名
 * - 支持加载状态管理
 * - 优化中文字体和样式
 */

import { useState, useCallback } from 'react';
import html2pdf from 'html2pdf.js';

/**
 * PDF 导出配置选项
 * @typedef {Object} PdfExportOptions
 * @property {string} filename - PDF 文件名（不含扩展名）
 * @property {number} margin - 页边距（英寸）
 * @property {string} format - 纸张格式（a4, letter等）
 * @property {string} orientation - 页面方向（portrait竖向, landscape横向）
 * @property {number} scale - 渲染缩放比例（影响清晰度）
 * @property {number} quality - 图片质量（0-1）
 */

/**
 * 默认 PDF 导出配置
 */
const DEFAULT_OPTIONS = {
  margin: 0.5,
  filename: 'document.pdf',
  image: { type: 'jpeg', quality: 0.98 },
  html2canvas: { 
    scale: 2, // 提高清晰度
    useCORS: true, // 允许跨域图片
    logging: false, // 禁用日志
    letterRendering: true, // 改善文字渲染
    onclone: function(clonedDoc) {
      // 在克隆的文档中移除所有包含 oklch 的样式
      const styles = clonedDoc.querySelectorAll('style');
      styles.forEach(style => {
        if (style.textContent && (
          style.textContent.includes('oklch') || 
          style.textContent.includes('oklab') ||
          style.textContent.includes('lch(') ||
          style.textContent.includes('lab(')
        )) {
          // 移除包含现代颜色函数的样式规则
          style.textContent = style.textContent
            .replace(/oklch\([^)]+\)/g, 'rgb(0, 0, 0)')
            .replace(/oklab\([^)]+\)/g, 'rgb(0, 0, 0)')
            .replace(/lch\([^)]+\)/g, 'rgb(0, 0, 0)')
            .replace(/lab\([^)]+\)/g, 'rgb(0, 0, 0)');
        }
      });
    },
    ignoreElements: function(element) {
      // 忽略可能导致问题的元素
      return element.classList?.contains('no-pdf-export');
    },
  },
  jsPDF: { 
    unit: 'in', 
    format: 'a4', 
    orientation: 'portrait',
    compress: true // 启用压缩
  },
  // 分页控制
  pagebreak: { 
    mode: ['avoid-all', 'css', 'legacy'],
    before: '.page-break-before',
    after: '.page-break-after',
    avoid: ['img', 'pre', 'code', 'table']
  }
};

/**
 * PDF 导出 Hook
 * @returns {Object} { exportToPdf, isExporting, error }
 */
export const usePdfExport = () => {
  const [isExporting, setIsExporting] = useState(false);
  const [error, setError] = useState(null);

  /**
   * 导出 PDF 函数
   * @param {HTMLElement|string} element - 要导出的 DOM 元素或选择器
   * @param {PdfExportOptions} options - 导出配置选项
   */
  const exportToPdf = useCallback(async (element, options = {}) => {
    try {
      setIsExporting(true);
      setError(null);

      // 获取目标元素
      let targetElement;
      if (typeof element === 'string') {
        targetElement = document.querySelector(element);
      } else {
        targetElement = element;
      }

      if (!targetElement) {
        throw new Error('未找到要导出的元素');
      }

      // 保存默认的 onclone 回调
      const defaultOnClone = DEFAULT_OPTIONS.html2canvas.onclone;
      const customOnClone = options.html2canvas?.onclone;
      
      // 合并配置选项
      const mergedOptions = {
        ...DEFAULT_OPTIONS,
        ...options,
        image: { ...DEFAULT_OPTIONS.image, ...options.image },
        html2canvas: { 
          ...DEFAULT_OPTIONS.html2canvas, 
          ...options.html2canvas,
          // 合并 onclone 回调：先执行默认的，再执行自定义的
          onclone: function(clonedDoc) {
            if (defaultOnClone) defaultOnClone(clonedDoc);
            if (customOnClone) customOnClone(clonedDoc);
          }
        },
        jsPDF: { ...DEFAULT_OPTIONS.jsPDF, ...options.jsPDF },
        pagebreak: { ...DEFAULT_OPTIONS.pagebreak, ...options.pagebreak }
      };

      // 等待所有图片加载完成
      await waitForImagesToLoad(targetElement);

      // 克隆元素以避免影响原始 DOM
      const clonedElement = targetElement.cloneNode(true);
      
      // 优化样式（确保在 PDF 中正确显示）
      optimizeStylesForPdf(clonedElement);

      // 生成 PDF
      await html2pdf()
        .set(mergedOptions)
        .from(clonedElement)
        .save();

      console.log('PDF 导出成功');
    } catch (err) {
      console.error('PDF 导出失败:', err);
      setError(err.message || '导出失败，请重试');
      throw err;
    } finally {
      setIsExporting(false);
    }
  }, []);

  /**
   * 重置错误状态
   */
  const resetError = useCallback(() => {
    setError(null);
  }, []);

  return {
    exportToPdf,
    isExporting,
    error,
    resetError
  };
};

/**
 * 等待元素中的所有图片加载完成
 * @param {HTMLElement} element - 目标元素
 * @returns {Promise<void>}
 */
const waitForImagesToLoad = (element) => {
  const images = element.querySelectorAll('img');
  const promises = Array.from(images).map(img => {
    if (img.complete) {
      return Promise.resolve();
    }
    return new Promise((resolve, reject) => {
      img.onload = resolve;
      img.onerror = () => {
        console.warn('图片加载失败:', img.src);
        resolve(); // 即使失败也继续
      };
      // 超时保护（5秒）
      setTimeout(resolve, 5000);
    });
  });
  return Promise.all(promises);
};

/**
 * 优化样式以确保在 PDF 中正确显示
 * @param {HTMLElement} element - 要优化的元素
 */
const optimizeStylesForPdf = (element) => {
  // 设置白色背景（避免透明背景）
  element.style.backgroundColor = 'white';
  element.style.padding = '20px';
  
  // 转换所有 oklch 和其他现代颜色函数为标准颜色
  convertModernColorsToStandard(element);
  
  // 确保代码块不被截断
  const codeBlocks = element.querySelectorAll('pre, code');
  codeBlocks.forEach(block => {
    block.style.pageBreakInside = 'avoid';
    block.style.whiteSpace = 'pre-wrap';
    block.style.wordBreak = 'break-word';
  });

  // 确保表格不被截断
  const tables = element.querySelectorAll('table');
  tables.forEach(table => {
    table.style.pageBreakInside = 'avoid';
    table.style.fontSize = '12px'; // 稍微减小字体避免溢出
  });

  // 确保图片适应页面宽度
  const images = element.querySelectorAll('img');
  images.forEach(img => {
    img.style.maxWidth = '100%';
    img.style.height = 'auto';
    img.style.pageBreakInside = 'avoid';
  });

  // 优化标题样式
  const headings = element.querySelectorAll('h1, h2, h3, h4, h5, h6');
  headings.forEach(heading => {
    heading.style.pageBreakAfter = 'avoid';
    heading.style.color = '#000'; // 确保标题在 PDF 中可见
  });

  // 确保链接在 PDF 中可见
  const links = element.querySelectorAll('a');
  links.forEach(link => {
    link.style.color = '#0066cc';
    link.style.textDecoration = 'underline';
  });
};

/**
 * 转换现代颜色函数（oklch, oklab, lch, lab 等）为标准颜色
 * html2canvas 不支持这些新颜色函数，需要转换为 rgb/rgba/hex
 * @param {HTMLElement} element - 要处理的元素
 */
const convertModernColorsToStandard = (element) => {
  // 获取所有元素（包括自身）
  const allElements = [element, ...element.querySelectorAll('*')];
  
  allElements.forEach(el => {
    try {
      const computedStyle = window.getComputedStyle(el);
      
      // 需要检查的颜色属性列表
      const colorProperties = [
        'color',
        'backgroundColor',
        'borderColor',
        'borderTopColor',
        'borderRightColor',
        'borderBottomColor',
        'borderLeftColor',
        'outlineColor',
        'textDecorationColor',
        'fill',
        'stroke'
      ];
      
      colorProperties.forEach(prop => {
        const value = computedStyle[prop];
        
        // 检查是否包含现代颜色函数
        if (value && (
          value.includes('oklch') || 
          value.includes('oklab') || 
          value.includes('lch') || 
          value.includes('lab')
        )) {
          // 获取计算后的颜色（浏览器会自动转换为 rgb/rgba）
          const computedColor = computedStyle[prop];
          
          // 如果浏览器已经转换为 rgb/rgba，直接使用
          if (computedColor && (computedColor.startsWith('rgb') || computedColor.startsWith('#'))) {
            el.style[prop] = computedColor;
          } else {
            // 创建临时元素来获取转换后的颜色
            const tempDiv = document.createElement('div');
            tempDiv.style.color = value;
            document.body.appendChild(tempDiv);
            const convertedColor = window.getComputedStyle(tempDiv).color;
            document.body.removeChild(tempDiv);
            
            el.style[prop] = convertedColor;
          }
        }
      });
    } catch (error) {
      // 忽略单个元素的错误，继续处理其他元素
      console.warn('颜色转换警告:', error);
    }
  });
};

export default usePdfExport;

